/**
 * @param {Object} initConfig 地图对象定义
 */
function BkolDraw() {
    this._init_();
}

BkolDraw.prototype = {
    constructor: BkolDraw,
    _init_: function () {
        this.oplGeoJson = new ol.format.GeoJSON();
        this.oplWktJson = new ol.format.WKT();
        this.parser = new jsts.io.OL3Parser();
        this.parser.inject(ol.geom.Point, ol.geom.LineString, ol.geom.LinearRing, ol.geom.Polygon, ol.geom.MultiPoint, ol.geom.MultiLineString, ol.geom.MultiPolygon);
    },
    feature2GeoJson: function (feature) {
        return this.oplGeoJson.writeFeatureObject(feature);
    },
    geoJson2feature: function (geo) {
        return this.oplGeoJson.readFeature(geo);
    },
    wkt2feature: function (geo) {
        return this.oplWktJson.readFeature(geo);
    },
    feature2Wkt: function (feature) {
        return this.oplWktJson.writeFeatureText(feature);
    },
    geometry2GeoJson: function (geometry) {
        return this.oplGeoJson.writeGeometryObject(geometry);
    },
    getPoint: function (x, y) {
        return new ol.geom.Point([parseFloat(x), parseFloat(y)])
    },

    getCenterPoint :function(feature){
      var geojson = this.feature2GeoJson(feature)
      var centr = turf.centroid(geojson)
      var c_lng = centr.geometry.coordinates[0];
      var c_lat = centr.geometry.coordinates[1];
      return [c_lng,c_lat]
    },
    /**
     * 画线裁剪或扩展面
     * @param polygon
     * @param line
     */
    lineModifyPolygon: function (polygon, line) {
        // try{
        //     //将openlayer的feature面对象转为turf所需的geojson面
        //     var turf_polygon = this.feature2GeoJson(polygon);
        //
        //     //将面转成线
        //     var turf_polygon_line = turf.polygonToLine(turf_polygon);
        //
        //     //将openlayer的feature线对象转为turf所需的geojson线
        //     var turf_line = this.feature2GeoJson(line);
        //
        //     //获取面转化成的线和圈画线的相交点
        //     var intersect_points = turf.lineIntersect(turf_polygon_line, turf_line);
        //
        //     if(intersect_points.features.length<2){
        //         return polygon;
        //     } else if(intersect_points.features.length==2) {
        //         //如果相交点有2个
        //         var start = intersect_points.features[0];
        //         var stop = intersect_points.features[1];
        //
        //         var ls_polygon = turf.lineSlice(start, stop, turf_polygon_line);
        //
        //         var ls_line = turf.lineSlice(start, stop, turf_line);
        //
        //         // debugger;
        //         var collection = turf.featureCollection([ls_polygon,ls_line]);
        //         var intersect_polygon = turf.lineToPolygon(collection);
        //
        //         return [this.geoJson2feature(intersect_polygon)];
        //
        //         var isContains = turf.booleanContains(turf_polygon,intersect_polygon);
        //
        //         var feature_return = null;
        //         if(isContains){
        //             feature_return = this.geoJson2feature(turf.mask(turf_polygon, intersect_polygon));
        //         }else{
        //             feature_return = this.geoJson2feature(turf.union(turf_polygon, intersect_polygon));
        //         }
        //
        //         return feature_return;
        //     } else {
        //         return null;
        //     }
        // } catch(e) {
        //     console.log("编辑失败：");
        //     return null;
        // }
    },
    /**
     * 判断面是否相交 如果不相交返回true
     * @param polygon
     * @param polygon2
     */
    Disjoin: function (polygon, polygon2) {
        //被编辑图斑
        var turf_polygon = this.feature2GeoJson(polygon);
        //圈画图斑
        var turf_polygon2 = this.feature2GeoJson(polygon2);
        var b = turf.booleanDisjoint(turf_polygon, turf_polygon2);
        return b;
    },
    /**
     * 画面裁剪或扩展面：第一个点在面里为扩展，在面外为裁剪
     * @param polygon
     * @param polygon2
     * @param geojson  true：返回geojson
     */
    polygonModifyPolygon: function (polygon, polygon2, geojson) {
        //被编辑图斑
        var turf_polygon = this.feature2GeoJson(polygon);

        //圈画图斑
        var turf_polygon2 = this.feature2GeoJson(polygon2);

        //圈画图斑的第一点
        var first_point = turf.explode(turf_polygon2).features[0];

        var feature_return = null;
        //圈画图斑的第一个点如果在被编辑图斑外，则判定为裁剪，如果在图斑内，判定为扩展
        if (turf.booleanPointInPolygon(first_point, turf_polygon)) {
            var union = turf.union(turf_polygon, turf_polygon2);
            if (geojson) {
                feature_return = union;
            } else {
                feature_return = this.geoJson2feature(union);
            }
        } else {
            var difference = turf.difference(turf_polygon, turf_polygon2);
            if (geojson) {
                feature_return = difference;
            } else {
                feature_return = this.geoJson2feature(difference);
            }
        }

        return feature_return;
    },

    /**
     * 对面进行挖洞操作
     * @param polygon
     * @param hole
     */
    digHoleToPolygon: function (polygon, hole) {
        //被编辑图斑
        var turf_polygon = this.feature2GeoJson(polygon);

        //圈画图斑
        var turf_hole = this.feature2GeoJson(hole);

        var masked = turf.difference(turf_polygon, turf_hole);

        return this.geoJson2feature(masked);
    },

    /**
     * 对面进行补洞操作
     * @param polygon
     * @param hole
     */
    fillHoleToPolygon: function (polygon, fill) {
        //被编辑图斑
        var turf_polygon = this.feature2GeoJson(polygon);

        //圈画图斑
        var turf_fill = this.feature2GeoJson(fill);

        var union = turf.union(turf_polygon, turf_fill);

        return this.geoJson2feature(union);
    },

    /**
     * 面合并
     * @param PolygonCollection
     * @returns {*}
     */
    mergePolygon: function (PolygonCollection) {
        if (PolygonCollection.length < 2) {
            console.log("图斑数量小于2，不可合并");
            return;
        }

        var turf_polygon1 = this.feature2GeoJson(PolygonCollection[0]);
        var turf_polygon2 = this.feature2GeoJson(PolygonCollection[1]);

        var turf_polygon = turf.union(turf_polygon1, turf_polygon2);

        for (var i = 2; i < PolygonCollection.length; i++) {
            var turf_polygon_ = this.feature2GeoJson(PolygonCollection[i]);
            turf_polygon = turf.union(turf_polygon, turf_polygon_);
        }

        return this.geoJson2feature(turf_polygon);
    },

    /**
     * 用面拆分面
     * @param polygon
     * @param split
     */
    splitPolygon: function (polygon, split) {
        var turf_polygon = this.feature2GeoJson(polygon);

        var turf_split = this.feature2GeoJson(split);

        var b = turf.booleanDisjoint(turf_polygon, turf_split);
        if (b) {
            return [polygon];
        }
        var featureCollection = [];
        var turf_difference = turf.difference(turf_polygon, turf_split);
        featureCollection.push(this.geoJson2feature(turf_difference));

        var turf_intersect = turf.intersect(turf_polygon, turf_split);
        featureCollection.push(this.geoJson2feature(turf_intersect));

        return featureCollection;
    },

    /**
     * 用面拆分面
     * @param polygon
     * @param split
     */
    splitPolygonJsts: function (polygon, split) {
        var turf_pro = this.feature2GeoJson(polygon);

        var Properties = turf_pro.properties;
        var turf_polygon = this.parser.read(polygon.getGeometry());
        var turf_split = this.parser.read(split.getGeometry());
        if (!turf_polygon.intersects(turf_split)) {
            return [polygon];
        }
        if (turf_polygon.within(turf_split)) {
            return [polygon];
        }
        var inter = turf_polygon.intersection(turf_split);
        var outer = turf_polygon.difference(turf_split);
        var featureCollection = [];
        var inters = this.breakPolygonJsts(inter, Properties);
        var outers = this.breakPolygonJsts(outer, Properties);
        featureCollection = featureCollection.concat(inters).concat(outers);
        return featureCollection;
    },
    /**
     * 打散
     * @param polygon
     * @param split
     */
    breakPolygon: function (polygon) {
        var turf_pro = this.feature2GeoJson(polygon);
        var Properties = turf_pro.properties;
        var jsts_polygon = this.parser.read(polygon.getGeometry());
        var featureCollection = this.breakPolygonJsts(jsts_polygon, Properties);
        return featureCollection;
    },
    breakPolygonJsts: function (jsts_polygon, Properties) {
        var featureCollection = [];
        if (jsts_polygon.getGeometryType() != "MultiPolygon" && jsts_polygon.getGeometryType() != "GeometryCollection") {
            var fs = this.jstsPolygonTofeature(jsts_polygon, Properties);
            featureCollection.push(fs);
            return featureCollection;
        }
        for (var i = 0; i < jsts_polygon._geometries.length; i++) {
            var gem = jsts_polygon._geometries[i];
            if (gem.getGeometryType() == "Polygon") {
                var fs = this.jstsPolygonTofeature(gem, Properties);
                featureCollection.push(fs);
            } else if (gem.getGeometryType() == "MultiPolygon") {
                for (var j = 0; j < jsts_polygon._geometries.length; i++) {
                    var gem = jsts_polygon._geometries[j];
                    if (gem.getGeometryType() == "Polygon") {
                        var fs = this.jstsPolygonTofeature(gem, Properties);
                        featureCollection.push(fs)
                    }
                }
            }
        }
        return featureCollection;
    },
    jstsPolygonTofeature: function (jsts_polygon, Properties) {
        var outergeo = (new ol.format.GeoJSON()).writeGeometryObject(this.parser.write(jsts_polygon));
        var fs = this.geoJson2feature(outergeo);
        fs.setProperties(Properties);
        return fs;
    },
    clone: function (obj) {
        var $this = this;
        if (null == obj || "object" != typeof obj) return obj;

        // Handle Date
        if (obj instanceof Date) {
            var copy = new Date();
            copy.setTime(obj.getTime());
            return copy;
        }

        // Handle Array
        if (obj instanceof Array) {
            var copy = [];
            for (var i = 0, len = obj.length; i < len; ++i) {
                copy[i] = $this.clone(obj[i]);
            }
            return copy;
        }

        // Handle Object
        if (obj instanceof Object) {
            var copy = {};
            for (var attr in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, attr)) copy[attr] = $this.clone(obj[attr]);
            }
            return copy;
        }
        throw new Error("Unable to copy obj! Its type isn't supported.");
    }
};
